import { FBSDataContextBase, DataContextFactory } from './../domain/fbsDataContext';
import { ServiceException } from "./serviceException";
import { OrderService } from '../service/orderService';

import { Guid, ObjectCopier, Logger } from "../common";

let moment = require('moment');
moment.locale('zh-cn');
require('../common/utils/moment-precise-range.js');
let lodash = require('lodash');
let webConfig = require('../../webconfig').webconfig;

export class WorkshiftService {
    // private ctx: FBSDataContextBase;
    private logger;
    private orderSvr: OrderService;
    constructor() {
        // this.ctx = DataContextFactory.GetDataContext();
        this.orderSvr = new OrderService();
        this.logger = new Logger().getLogger('app');
    }

    async generateWorkshiftInfo(closeTime, user, currentWorkshift) {
        let openTime = currentWorkshift.openTime;
        let storeId = webConfig.storeId;
        let data = await this.getTotalSales(
            user,
            openTime,
            closeTime,
            currentWorkshift
        );
        let durationTime = moment(moment(closeTime).startOf('minute')).locale('zh-cn').preciseDiff(moment(currentWorkshift.openTime).startOf('minute'));
        if (durationTime == '') durationTime = '1 分钟';
        var workshift = {
            id: Guid.GetGuid(),
            store: { id: storeId },
            clockin: { id: user.id, name: user.name },
            openTime: currentWorkshift.openTime,
            closeTime: closeTime,
            duration: durationTime,
            terminal: currentWorkshift.terminal,
            totalSales: data.totalSales,
            payments: data.payments,
            paymentsDetail: data.paymentsDetail,
            orders: data.orders,
            workingFund: currentWorkshift.workingFund
        };
        return workshift;
    }

    private async getTotalSales(user, openTime, closeTime, currentWorkshift) {
        let currentWorkshiftOrders = await this.orderSvr.GetWorkshiftOrders(
            openTime,
            closeTime
        );
        let data = {
            totalSales: {
                "quantity": 0,
                "amount": 0
            },
            payments: [],
            paymentsDetail: [],
            orders: []
        }
        if (currentWorkshiftOrders) {
            lodash.remove(currentWorkshiftOrders, function (order) {
                return order.status == 'merged'
                    || (
                        order.sourceid == 'mpj/mstore/web-ordering'
                        && order.creator
                        && order.creator.id == 'weborder-customer'
                    );
            });
            let orderNum = currentWorkshiftOrders.length;
            //各种支付模式统计
            var totalSales = { quantity: 0, amount: 0 };
            //支付合计
            var payments = {};
            //支付详情
            var salesPay = {};
            var refundPay = {};
            //订单类型统计
            var orders = [];
            var refundOrder = { orderType: 'refund', quantity: 0, amount: 0 };
            var salesOrder = { orderType: 'sales', quantity: 0, amount: 0 };
            var memberOrder = { orderType: 'macct-deposit', quantity: 0, amount: 0 };

            for (var i = 0; i < orderNum; i++) {
                if (currentWorkshiftOrders[i].checkout
                    && currentWorkshiftOrders[i].checkout.terminal.id != currentWorkshift.terminal.id) {
                    continue;
                }

                if (currentWorkshiftOrders[i].checkout) {
                    if (currentWorkshiftOrders[i].checkout && currentWorkshiftOrders[i].checkout.payments) {
                        //收入总额统计
                        totalSales.quantity++;
                        // totalSales.amount += currentWorkshiftOrders[i].amountDue;
                        //各种支付模式合计
                        this.getPayType(payments, currentWorkshiftOrders[i], openTime, closeTime);
                        for (var j = 0; j < currentWorkshiftOrders[i].checkout.payments.length; j++) {
                            if (currentWorkshiftOrders[i].checkout.payments[j].createTime > openTime
                                && currentWorkshiftOrders[i].checkout.payments[j].createTime < closeTime) {
                                totalSales.amount += Number(currentWorkshiftOrders[i].checkout.payments[j].amount);
                            }
                        }

                        //支付详情统计
                        let orderTmp = {};
                        if (currentWorkshiftOrders[i].orderType != 'refund') {
                            //支付统计
                            // currentWorkshiftOrders[i].txType = 'pay';
                            orderTmp = Object.assign(
                                currentWorkshiftOrders[i],
                                { txType: 'pay' }
                            );
                            this.getPayType(salesPay, orderTmp, openTime, closeTime)
                        } else {
                            // currentWorkshiftOrders[i].txType = 'refund';
                            orderTmp = Object.assign(
                                currentWorkshiftOrders[i],
                                { txType: 'refund' }
                            );
                            this.getPayType(refundPay, orderTmp, openTime, closeTime)
                        }
                        currentWorkshift[i] = orderTmp;
                    }

                    //订单类型统计
                    if (currentWorkshiftOrders[i].orderType) {
                        switch (currentWorkshiftOrders[i].orderType) {
                            //销售单
                            case 'sales':
                                if (currentWorkshiftOrders[i].checkout) {
                                    salesOrder.quantity++;
                                    salesOrder.amount = this.accAdd(salesOrder.amount, currentWorkshiftOrders[i].amountDue);
                                }
                                break;
                            //退单
                            case 'refund':
                                refundOrder.quantity++;
                                refundOrder.amount = this.accAdd(refundOrder.amount, currentWorkshiftOrders[i].amountDue);
                                break;
                            case 'macct-deposit':
                                memberOrder.quantity++;
                                memberOrder.amount = this.accAdd(memberOrder.amount, currentWorkshiftOrders[i].amountDue);
                                break;
                        }
                    }
                }
            }

            var paymentsDetail = this.setPaymentToArray(salesPay).concat(
                this.setPaymentToArray(refundPay)
            );
            refundOrder.amount ? orders.push(refundOrder) : null;
            salesOrder.amount ? orders.push(salesOrder) : null;
            memberOrder.amount ? orders.push(memberOrder) : null;

            data.totalSales = totalSales;
            data.payments = this.setPaymentToArray(payments);
            data.paymentsDetail = paymentsDetail;
            data.orders = orders;
        }
        return data;
    }

    //支付类型统计
    private getPayType(payType, order, openTime, closeTime) {
        for (var j = 0, paymentLength = order.checkout.payments.length; j < paymentLength; j++) {
            let channel = order.checkout.payments[j].channel;
            if (!payType[channel]) {
                var amount = 0;
                if (order.isCounter) {
                    if (order.checkout.payments[j].createTime > openTime && order.checkout.payments[j].createTime < closeTime) {
                        amount += Number(order.checkout.payments[j].amount);
                        payType[channel] = { channel: channel, amount: amount, quantity: 1 };
                        if (order.txType) {
                            payType[channel].txType = order.txType;
                        }
                    }
                } else {
                    amount += Number(order.checkout.payments[j].amount);
                    payType[channel] = { channel: channel, amount: amount, quantity: 1 };
                    if (order.txType) {
                        payType[channel].txType = order.txType;
                    }
                }
            } else {

                if (order.isCounter) {
                    if (order.checkout.payments[j].createTime > openTime && order.checkout.payments[j].createTime < closeTime) {
                        payType[channel].quantity++;
                        payType[channel].amount = this.accAdd(payType[channel].amount, order.checkout.payments[j].amount);
                        if (order.txType) {
                            payType[channel].txType = order.txType;
                        }
                    }

                } else {
                    payType[channel].quantity++;
                    payType[channel].amount = this.accAdd(payType[channel].amount, order.checkout.payments[j].amount);
                    if (order.txType) {
                        payType[channel].txType = order.txType;
                    }
                }
            }
        }
    }

    private setPaymentToArray(payments) {
        var paymentsToArray = [];
        for (var key in payments) {
            var payment: any = { channel: key, amount: payments[key].amount, quantity: payments[key].quantity };
            if (payment.amount != 0) {
                if (payments[key].txType) {
                    payment.txType = payments[key].txType;
                }
                paymentsToArray.push(payment);
            }
        }
        return paymentsToArray;
    }

    // 加法
    // TODO：需要替换成公共库中的方法
    private accAdd(numberA, numberB) {
        let result = Number(numberA) + Number(numberB);
        return parseFloat(parseFloat(result.toString()).toFixed(3));
    }
}